// services/json_parser_service.dart
import 'dart:convert';
import 'package:get/get.dart';
import '../models/field_info.dart';

class JsonParserService extends GetxService {
  
  // 将JSON字符串转换为FieldInfo列表
  List<FieldInfo> parseJsonString(String jsonString) {
    try {
      final parsedJson = json.decode(jsonString);
      return _parseDynamic('root', parsedJson);
    } catch (e) {
      Get.snackbar('解析错误', '无法解析JSON字符串: $e');
      return [];
    }
  }

  // 递归解析动态数据
  List<FieldInfo> _parseDynamic(String name, dynamic data, {String? description}) {

    if (data == null) {
      return [FieldInfo(name: name, type: FieldType.nullType, description: description)];
    }
    
    if (data is String) {
      return [FieldInfo(name: name, type: FieldType.string, value: data, description: description)];
    } else if (data is int || data is double) {
      return [FieldInfo(name: name, type: FieldType.number, value: data, description: description)];
    } else if (data is bool) {
      return [FieldInfo(name: name, type: FieldType.boolean, value: data, description: description)];
    } else if (data is List) {
      return _parseList(name, data, description: description);
    } else if (data is Map<String, dynamic>) {
      return _parseObject(name, data, description: description);
    } else {
      return [FieldInfo(name: name, type: FieldType.unknown, value: data.toString(), description: description)];
    }
  }

  // 解析数组类型
  List<FieldInfo> _parseList(String name, List<dynamic> list, {String? description}) {
    if (list.isEmpty) {
      return [FieldInfo(name: name, type: FieldType.array, description: description)];
    }
    
    // 获取数组第一个元素作为样本分析类型
    final sample = list[0];
    final children = _parseDynamic('0', sample);
    
    return [
      FieldInfo(
        name: name,
        type: FieldType.array,
        description: description,
        children: children,
      )
    ];
  }

  // 解析对象类型
  List<FieldInfo> _parseObject(String name, Map<String, dynamic> obj, {String? description}) {
    final List<FieldInfo> children = [];
    
    obj.forEach((key, value) {
      children.addAll(_parseDynamic(key, value));
    });
    
    return [
      FieldInfo(
        name: name,
        type: FieldType.object,
        description: description,
        children: children,
      )
    ];
  }

  // 将FieldInfo转换回JSON
  dynamic convertToJson(List<FieldInfo> fields) {
    if (fields.length == 1 && fields[0].name == 'root') {
      return _fieldToDynamic(fields[0]);
    }
    return fields.map((field) => _fieldToDynamic(field)).toList();
  }

  dynamic _fieldToDynamic(FieldInfo field) {
    switch (field.type) {
      case FieldType.string:
      case FieldType.number:
      case FieldType.boolean:
        return field.value;
      case FieldType.array:
        if (field.children == null || field.children!.isEmpty) {
          return [];
        }
        // 对于数组，我们假设所有子元素类型相同
        return field.children!.map((child) => _fieldToDynamic(child)).toList();
      case FieldType.object:
        if (field.children == null) {
          return {};
        }
        final Map<String, dynamic> result = {};
        for (final child in field.children!) {
          result[child.name] = _fieldToDynamic(child);
        }
        return result;
      case FieldType.nullType:
        return null;
      default:
        return field.value?.toString();
    }
  }

  // 查找字段的父节点
  FieldInfo? findParentField(List<FieldInfo> fields, String targetId, [FieldInfo? parent]) {
    for (final field in fields) {
      if (field.id == targetId) {
        return parent;
      }
      
      if (field.children != null && field.children!.isNotEmpty) {
        final foundParent = findParentField(field.children!, targetId, field);
        if (foundParent != null) {
          return foundParent;
        }
      }
    }
    return null;
  }

  // 通过ID查找字段
  FieldInfo? findFieldById(List<FieldInfo> fields, String id) {
    for (final field in fields) {
      if (field.id == id) {
        return field;
      }
      
      if (field.children != null && field.children!.isNotEmpty) {
        final foundField = findFieldById(field.children!, id);
        if (foundField != null) {
          return foundField;
        }
      }
    }
    return null;
  }
}